home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 22
/
Aminet 22 (1997)(GTI - Schatztruhe)[!][Dec 1997].iso
/
Aminet
/
util
/
misc
/
cookietool.lha
/
cookietool
/
cdbsplit.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-10-25
|
11KB
|
351 lines
/*========================================================================*\
| File: cdbsplit.c Date: 25 Oct 1997 |
*------------------------------------------------------------------------*
| Split parts off your cookie database, by keyword, by line length, |
| by number of lines, or as groups of "similar" cookies. |
| Expected file format is plain text with a "%%" line ending each cookie.|
| See help() for usage notes. |
| |
\*========================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "strstuff.h"
char version[] = "$VER: cdbsplit 2.2 (25.10.97)";
#define FBUFSIZE 16384 /* we'll use larger file buffers */
#define CBUFSIZE 32000L
#define LBUFSIZE 2000
#define NTARGET 10 /* max. number of keywords to search for */
char line[LBUFSIZE]; /* large enough to hold the longest line */
char cbuf[CBUFSIZE]; /* large enough to hold one complete cookie */
char cbak[CBUFSIZE]; /* backup of the last cookie, to find groups */
char uppercase[256]; /* conversion table */
int l_min = 1, l_max = 0, w_min = 1, w_max = 0;
long n_min = 1, n_max = 0;
int matchlen = 0;
char *rtarget[NTARGET]; /* required keywords */
char *otarget[NTARGET]; /* optional keywords */
int required = 0, optional = 0;
/*
* print a help text and nag about illegal parameter <s>
*/
void help( char *s )
{
if( s )
printf( "illegal option '%s'\n", s );
printf( "usage: cdbsplit [options] <cookiefile> <newfile>\n" );
printf( "where options are:\n" );
printf( " -k<keywd> / -K<keywd> search for optional / required keyword\n" );
printf( " -l<lines> / -L<lines> range for number of lines in a cookie\n" );
printf( " -w<width> / -W<width> range for cookie line width\n" );
printf( " -n<no.> / -N<no.> range of cookie numbers\n" );
printf( " -m<m> extract groups of cookies with <m> matching chars\n" );
printf( " -d[0-3] how fussy about word delimiters? (default: 2) \n" );
printf( " -c case sensitive comparisons\n" );
printf( " -x extract only, do not modify the input file\n" );
printf( " -a append to an existing output file\n" );
}
int dispatch( char *cookie, int good, FILE *fp2, FILE *fp3 )
{
long result = 1;
if( good )
result = fprintf( fp2, "%s%%%%\n", cookie );
else if( fp3 )
result = fprintf( fp3, "%s%%%%\n", cookie );
if( result <= 0 )
{
printf( "\nfile error, aborted !!!\n" );
exit( 20 );
}
return good ? 1 : 0;
}
long filter_cookies( FILE *fp1, FILE *fp2, FILE *fp3 )
/* scatter contents of <fp1> across <fp2> (hitfile) and <fp3> (dumpfile),
* return value is the number of cookies in the dumpfile
*/
{
long count = 0, hits = 0, cbuflen;
int ok = 0, ok2, lines, width, w, i;
strcpy( cbak, "" );
strcpy( cbuf, "" );
cbuflen = lines = width = 0;
while( fgets( line, LBUFSIZE, fp1 ) )
{
if( strncmp( line, "%%", 2 ) == 0 )
{ /* "end of cookie"-marker */
count++;
/* perform the checks: */
if( matchlen ) /* "similar cookies" mode */
{
ok2 = ok;
ok = (strn_cmp( cbak, cbuf, matchlen ) == 0);
if( *cbak ) /* skip the first loop */
hits += dispatch( cbak, ok || ok2, fp2, fp3 );
strcpy( cbak, cbuf );
}
else /* standard mode */
{
ok = (lines >= l_min && width >= w_min && count >= n_min);
if( l_max )
ok = ok && ( lines <= l_max );
if( w_max )
ok = ok && ( width <= w_max );
if( n_max )
ok = ok && ( count <= n_max );
if( ok ) /* string checks still necessary? */
{
if( required == 0 && optional > 0 )
ok = 0;
for( i = 0; i < required; i++ )
ok = ok && (str_str( cbuf, rtarget[i] ) != NULL);
for( i = 0; i < optional; i++ )
ok = ok || (str_str( cbuf, otarget[i] ) != NULL);
}
hits += dispatch( cbuf, ok, fp2, fp3 );
}
if( count % 100 == 0 )
{
printf( "%ld hits/%ld misses.\r", hits, count - hits );
fflush( stdout );
}
strcpy( cbuf, "" ); /* start a new cookie */
cbuflen = lines = width = 0;
}
else /* add a line to the current cookie */
{
w = strlen( line );
if( (cbuflen += w) >= CBUFSIZE )
{
printf( "\ncookie too big (>%ld chars) \n", CBUFSIZE );
exit( 20 );
}
strcat( cbuf, line );
lines++;
if( w > width )
width = w;
}
}
if( matchlen ) /* one cookie still pending in this mode */
hits += dispatch( cbak, ok, fp2, fp3 );
printf( "Done, %ld hits out of %ld\n", hits, count );
return (count - hits);
}
void confirm_options()
/* tell the user what his options will do */
{
int flags, i;
if( matchlen )
printf( " searching for groups of cookies with "
"%d matching characters.\n", matchlen );
else
{
flags = 0xf; /* what restrictions do apply? */
if( optional + required > 0 )
{
printf( " search string%s: ", (optional + required > 1) ? "s" : "");
if( required > 1 && optional > 0 )
printf("(");
if( required > 0 )
{
printf( "\"%s\"", rtarget[0] );
for( i = 1; i < required; i++ )
printf( " && \"%s\"", rtarget[i] );
}
if( required > 1 && optional > 0 )
printf(")");
if( required > 0 && optional > 0 )
printf(" || ");
if( optional > 0 )
{
printf( "\"%s\"", otarget[0] );
for( i = 1; i < optional; i++ )
printf( " || \"%s\"", otarget[i] );
}
printf( "\n" );
}
else
flags ^= 1;
if( l_max )
printf( " looking for cookies %d - %d lines long.\n", l_min, l_max );
else if( l_min > 1 )
printf( " looking for cookies at least %d lines long.\n", l_min );
else
flags ^= 2;
if( w_max )
printf( " looking for cookies %d - %d columns wide.\n", w_min, w_max );
else if( w_min > 1 )
printf( " looking for cookies at least %d columns wide.\n", w_min );
else
flags ^= 4;
if( n_max )
printf( " considering cookies #%ld - #%ld only.\n", n_min, n_max);
else if( n_min > 1 )
printf( " starting at cookie #%ld.\n", n_min );
else
flags ^= 8;
if( flags == 0 )
printf( " no restrictions.\n" );
}
}
int main( int argc, char *argv[] )
{
char *s;
char *name1 = NULL, *name2 = NULL, *name3 = "cdb_temp_kickme";
int append = 0, move = 1;
int case_sense = 0, bordermode = 2;
long dumped;
FILE *infile, *hitfile, *dumpfile;
if( argc < 3 )
{
help( NULL );
return 5;
}
while( --argc )
{
s = *++argv;
if( *s != '-' )
{
if( name1 == NULL )
name1 = s;
else
name2 = s;
}
else
{
s++;
switch( *s++ )
{
case 'k':
if( optional < NTARGET )
otarget[ optional++ ] = s;
break;
case 'K':
if( required < NTARGET )
rtarget[ required++ ] = s;
break;
case 'm':
matchlen = atoi( s );
break;
case 'l':
l_min = atoi( s );
break;
case 'L':
l_max = atoi( s );
break;
case 'w':
w_min = atoi( s );
break;
case 'W':
w_max = atoi( s );
break;
case 'n':
n_min = atol( s );
break;
case 'N':
n_max = atol( s );
break;
case 'a':
append = 1;
break;
case 'x':
move = 0;
break;
case 'c':
case_sense = 1;
break;
case 'd':
if( isdigit( *++s ) )
bordermode = atoi( s );
else
{
help( argv[0] );
return 5;
}
break;
default:
help( argv[0] );
return 5;
}
}
}
str_setup( bordermode, case_sense ); /* !!! */
if( name1 == NULL || name2 == NULL )
{
help( NULL );
return 5;
}
if( !(infile = fopen( name1, "r" ) ) )
{
printf( "Can't open '%s' for input!\n", name1 );
return 10;
}
setvbuf( infile, NULL, _IOFBF, FBUFSIZE );
if( !append && (hitfile = fopen( name2, "r" )) )
{
printf( "Error: '%s' exists! Use -a to append.\n", name2 );
return 10;
}
if( !(hitfile = fopen( name2, "a" )) )
{
printf( "Can't open '%s' for output!\n", name2 );
return 10;
}
setvbuf( hitfile, NULL, _IOFBF, FBUFSIZE );
if( move )
{
if( !(dumpfile = fopen( name3, "w" ) ) )
{
printf( "Can't open '%s' for output!\n", name3 );
return 10;
}
setvbuf( dumpfile, NULL, _IOFBF, FBUFSIZE );
}
else
dumpfile = NULL;
printf( "CdbSplit " );
print_strstat();
printf( "%sing from '%s' to '%s',\n", move ? "Mov" : "Copy", name1, name2 );
confirm_options();
/* OK, here we go: */
dumped = filter_cookies( infile, hitfile, dumpfile );
fclose( infile );
fclose( hitfile );
if( move )
{
fclose( dumpfile );
if( remove( name1 ) != 0 || rename( name3, name1 ) != 0 )
{
printf( "Couldn't overwrite the input file! Your cookies are in '%s'.\n", name3 );
return 5;
}
if( dumped == 0 )
{
remove( name1 );
printf( "'%s' is now empty and has been deleted.\n", name1 );
}
}
return 0;
}